"""
Main entrance for google app engine
Created on May, 2012
@author: Xiaoyuan XU
"""

import webapp2 #@UnresolvedImport
import os

from StringIO import StringIO
from datetime import date
from yahoofinance import YahooFinance, QuoteRecord #@UnusedImport
from google.appengine.ext.webapp.util import run_wsgi_app #@UnresolvedImport
from google.appengine.ext.db import Key #@UnresolvedImport

"""
Retrieve the list of symbol names from the symbol list
"""
def get_symbols():
	symbolsFilePath = os.path.join(os.path.dirname(__file__), 'symbollist.txt')
	inputFile = open(symbolsFilePath, 'r')
	symbols = []
	sp500 = inputFile.read()
	inputFile.close()
	for symbol in sp500.split():
		symbols.append(symbol)
	return symbols

"""
Entrance for loading the main page
"""
class MainPage(webapp2.RequestHandler):
	
	def __render_quotetable(self, startkey=""):
		PAGESIZE = 900
		quoteRecords = vars(QuoteRecord)['all']().order("__key__") 

		if startkey == "":
			try:
				startkey = quoteRecords.fetch(1)[0].key()
			except:
				return 
		else:
			startkey = Key(startkey)
			
		try:
			quoteRecords = quoteRecords.filter("__key__ >=", startkey).fetch(PAGESIZE+1)
		except:
			return

		stdout = StringIO()
		stdout.write("""
		  <table id = \'quoteTable\'>
		  	<tr><td>timestamp</td>
				<td>symbol</td>
				<td>data</td></tr>""")
		
		for quoteRecord in quoteRecords[:PAGESIZE]:
			stdout.write("<tr><td>%s</td>" % quoteRecord.timestamp)
			stdout.write("<td>%s</td>" %quoteRecord.symbol)
			stdout.write("<td>%s</td></tr>" %quoteRecord.quoteData)
		
		stdout.write("</table>")
		
		if len(quoteRecords) == PAGESIZE + 1:
			# quoteRecords[-1].key() is the startkey of next page
			stdout.write("""
				<p><a href="?startkey=%s"> Next</a></p>""" 
				% quoteRecords[-1].key())
			
		yahoofinance.validate_quoterecord(quoteRecords[:PAGESIZE])
		
		return stdout.getvalue()
		
	def get(self):

		self.response.out.write("""
			<html><body>
			  <form action="/validatequotedata" method="post">
			  	<div><input type="submit" value="Validate Quote Data"></div>
			  </form>
			  <form action="/queryyahoofinance" method="post">
			  	<div><input type="submit" value="Query Yahoo Finance"></div>
			  </form>
			  <form action="/downloadquote" method="GET" enctype="multipart/form-data">
			    <div>
					Symbol: <input type="text" name="symbolname"/>
			  		<input type="submit" value="Download Quotes">
			  	</div>
			  </form>""")

		self.response.out.write(
			self.__render_quotetable(startkey=self.request.get("startkey"))
			)
		
		self.response.out.write("""
			</body></html>""")
		
		
"""
Quey yahoo finance quote data and store in GAE data store 
Currently this query job is scheduled for every hour on weekdays
See cron.yaml
"""
class QueryYahooFinance(webapp2.RequestHandler):
	
	def __handle(self):
		
		# Only record the data on weekdays
		if date.today().weekday() >= 5:
			return
		
		symbols = get_symbols()
		batchsize = 10
		
		# batch our operation so that we send one request for every 10 symbols		
		while len(symbols) > 0:
			yahoofinance.query_currentquotes(symbols[:batchsize], quoteProperties)
			del symbols[:batchsize]
			
	def post(self):
		self.__handle()
		self.redirect("/")
		
	def get(self):
		self.__handle()	
		
"""
 Download the quote data of a symbol in a cvs file, i.e.(symbolname).cvs 
 URL: http://q-trading.appspot.com/downloadquote?symbolname=(symbolname)
"""
class DownloadQuote(webapp2.RequestHandler):
	
	def __handle(self):
		symbolNameStr = self.request.get("symbolname")
		symbols = symbolNameStr.split(",")
			
		self.response.headers['Content-Type'] = 'text/csv'
		self.response.headers['Content-Disposition'] = \
						"attachment; filename=" + str(symbolNameStr) + ".csv"

		stdout = StringIO()

		for symbol in symbols:
			stdout.writelines(yahoofinance.get_quoterecord(symbol))
							
		self.response.out.write(stdout.getvalue())
			
	def get(self):
		self.__handle()	

	def post(self):
		self.__handle()	

class ValidateQuoteData(webapp2.RequestHandler):
	
	def __handle(self):
		yahoofinance.validate_quoterecord()
		self.redirect("/")
			
	def get(self):
		self.__handle()	

	def post(self):
		self.__handle()	
		

# Propery tab string for yahoo finance 
# For the full list of propertties:
# http://code.google.com/p/yahoo-finance-managed/wiki/enumQuoteProperty
quoteProperties = 'sabcoghvl1jj5j6kk4k5j3b4'
yahoofinance = YahooFinance()

app = webapp2.WSGIApplication([('/', MainPage),
							   ('/validatequotedata', ValidateQuoteData),
							   ('/queryyahoofinance', QueryYahooFinance),
							   ('/downloadquote', DownloadQuote)],
							  debug=True)

def main():
	run_wsgi_app(app)

if __name__ == "__main__":
	main()
